{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 讯飞语音识别：基于自然语言处理，将自然语言音频转换为文本输出的技术。\n",
    "说明：该文档识别的是在test目录下的test_news_.wav文件，可更换文件或者使用云端链接页面，也可将识别结果储存为文档（取消文件部分的注释）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import base64\n",
    "import hashlib\n",
    "import hmac\n",
    "import json\n",
    "import os\n",
    "import time\n",
    "import requests\n",
    "lfasr_host = 'http://raasr.xfyun.cn/api'\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/prepare 成功:{'data': '58657b0fb90c4af1b9e39d67971d7199', 'err_no': 0, 'failed': None, 'ok': 0}\n",
      "/upload 成功:{'data': None, 'err_no': 0, 'failed': None, 'ok': 0}\n",
      "上传片1 成功\n",
      "/merge 成功:{'data': None, 'err_no': 0, 'failed': None, 'ok': 0}\n",
      "/getProgress 成功:{'data': '{\"status\":2,\"desc\":\"音频合并完成\"}', 'err_no': 0, 'failed': None, 'ok': 0}\n",
      "这个进程 58657b0fb90c4af1b9e39d67971d7199 正在处理中，进程状态： {\"status\":2,\"desc\":\"音频合并完成\"}\n",
      "/getProgress 成功:{'data': '{\"status\":9,\"desc\":\"转写结果上传完成\"}', 'err_no': 0, 'failed': None, 'ok': 0}\n",
      "进程 58657b0fb90c4af1b9e39d67971d7199 完成\n",
      "/getResult 成功:{'data': '[{\"bg\":\"0\",\"ed\":\"5250\",\"onebest\":\"16号出版的第二期求是杂志将发表中共中央总书记、国家主席、\",\"speaker\":\"0\"},{\"bg\":\"5250\",\"ed\":\"7850\",\"onebest\":\"中央军委主席习近平的重要文章，\",\"speaker\":\"0\"},{\"bg\":\"7910\",\"ed\":\"12420\",\"onebest\":\"正确认识和把握中长期经济社会发展重大问题。\",\"speaker\":\"0\"},{\"bg\":\"13000\",\"ed\":\"14110\",\"onebest\":\"文章强调，\",\"speaker\":\"0\"},{\"bg\":\"14120\",\"ed\":\"17790\",\"onebest\":\"十四五时期是我国全面建成小康社会，\",\"speaker\":\"0\"},{\"bg\":\"17790\",\"ed\":\"21570\",\"onebest\":\"实现第一个百年奋斗目标之后乘势而上，\",\"speaker\":\"0\"},{\"bg\":\"21570\",\"ed\":\"25630\",\"onebest\":\"开启全面建设社会主义现代化国家新征程，\",\"speaker\":\"0\"},{\"bg\":\"25630\",\"ed\":\"29740\",\"onebest\":\"向第二个百年奋斗目标进军的第一个5年，\",\"speaker\":\"0\"},{\"bg\":\"29810\",\"ed\":\"32410\",\"onebest\":\"我国将进入新发展阶段。\",\"speaker\":\"0\"},{\"bg\":\"33200\",\"ed\":\"34300\",\"onebest\":\"文章指出，\",\"speaker\":\"0\"},{\"bg\":\"34300\",\"ed\":\"38760\",\"onebest\":\"要以辩证思维看待新发展阶段的新机遇新挑战。\",\"speaker\":\"0\"},{\"bg\":\"39000\",\"ed\":\"41740\",\"onebest\":\"要增强机遇意识和风险意识，\",\"speaker\":\"0\"},{\"bg\":\"41740\",\"ed\":\"43010\",\"onebest\":\"准确时间，\",\"speaker\":\"0\"},{\"bg\":\"43010\",\"ed\":\"44050\",\"onebest\":\"科学应变，\",\"speaker\":\"0\"},{\"bg\":\"44050\",\"ed\":\"45180\",\"onebest\":\"主动求变，\",\"speaker\":\"0\"},{\"bg\":\"45190\",\"ed\":\"48440\",\"onebest\":\"勇于开顶风船，善于转危为机，\",\"speaker\":\"0\"},{\"bg\":\"48450\",\"ed\":\"50470\",\"onebest\":\"努力实现更高质量、\",\"speaker\":\"0\"},{\"bg\":\"50470\",\"ed\":\"55170\",\"onebest\":\"更有效率、更加公平、更可持续、更为安全的发展。\",\"speaker\":\"0\"},{\"bg\":\"55900\",\"ed\":\"59550\",\"onebest\":\"文章指出，要以畅通国民经济循环为主。\",\"speaker\":\"0\"}]', 'err_no': 0, 'failed': None, 'ok': 0}\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'RequestApi' object has no attribute 'getOnebest'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-26-fca9eb9a039c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m    198\u001b[0m     \u001b[0mfile_path\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34mr\"../test/test(news).m4a\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    199\u001b[0m     \u001b[0mapi\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mRequestApi\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mappid\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mAPP_ID\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msecret_key\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mSECRET_KEY\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mupload_file_path\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mfile_path\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 200\u001b[1;33m     \u001b[0mapi\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mall_api_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m<ipython-input-26-fca9eb9a039c>\u001b[0m in \u001b[0;36mall_api_request\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m    184\u001b[0m             \u001b[0mtime\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msleep\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    185\u001b[0m         \u001b[1;31m# 5 . 获取结果\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 186\u001b[1;33m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_result_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mtaskid\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mtaskid\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    187\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    188\u001b[0m \u001b[1;31m#把结果存入文件\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-26-fca9eb9a039c>\u001b[0m in \u001b[0;36mget_result_request\u001b[1;34m(self, taskid)\u001b[0m\n\u001b[0;32m    155\u001b[0m     \u001b[1;31m# 获取结果\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    156\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0mget_result_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtaskid\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 157\u001b[1;33m         \u001b[1;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgene_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mapi_get_result\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdata\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgene_params\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mapi_get_result\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtaskid\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mtaskid\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    158\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    159\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0mall_api_request\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32m<ipython-input-26-fca9eb9a039c>\u001b[0m in \u001b[0;36mgene_request\u001b[1;34m(self, apiname, data, files, headers)\u001b[0m\n\u001b[0;32m    102\u001b[0m             \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"{} 成功:\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mapiname\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mstr\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    103\u001b[0m             \u001b[1;32mif\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mapiname\u001b[0m\u001b[1;33m==\u001b[0m\u001b[1;34m\"/getResult\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 104\u001b[1;33m                 \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mgetOnebest\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    105\u001b[0m             \u001b[1;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    106\u001b[0m         \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mAttributeError\u001b[0m: 'RequestApi' object has no attribute 'getOnebest'"
     ]
    }
   ],
   "source": [
    "# 请求的接口名\n",
    "api_prepare = '/prepare'\n",
    "api_upload = '/upload'\n",
    "api_merge = '/merge'\n",
    "api_get_progress = '/getProgress'\n",
    "api_get_result = '/getResult'\n",
    "# 文件分片大小10M\n",
    "file_piece_sice = 10485760\n",
    "# ——————————————————转写可配置参数————————————————\n",
    "# 参数可在官网界面（https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html）查看，根据需求可自行在gene_params方法里添加修改\n",
    "# 转写类型\n",
    "lfasr_type = 0\n",
    "# 是否开启分词\n",
    "has_participle = 'false'\n",
    "has_seperate = 'true'\n",
    "# 多候选词个数\n",
    "max_alternatives = 0\n",
    "# 子用户标识\n",
    "suid = ''\n",
    "\n",
    "\n",
    "class SliceIdGenerator:\n",
    "    \"\"\"slice id生成器\"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        self.__ch = 'aaaaaaaaa`'\n",
    "\n",
    "    def getNextSliceId(self):\n",
    "        ch = self.__ch\n",
    "        j = len(ch) - 1\n",
    "        while j >= 0:\n",
    "            cj = ch[j]\n",
    "            if cj != 'z':\n",
    "                ch = ch[:j] + chr(ord(cj) + 1) + ch[j + 1:]\n",
    "                break\n",
    "            else:\n",
    "                ch = ch[:j] + 'a' + ch[j + 1:]\n",
    "                j = j - 1\n",
    "        self.__ch = ch\n",
    "        return self.__ch\n",
    "\n",
    "\n",
    "class RequestApi(object):\n",
    "    def __init__(self, appid, secret_key, upload_file_path):\n",
    "        self.appid = appid\n",
    "        self.secret_key = secret_key\n",
    "        self.upload_file_path = upload_file_path\n",
    "\n",
    "    # 根据不同的apiname生成不同的参数,本示例中未使用全部参数可在官网(https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html)查看后选择适合业务场景的进行更换\n",
    "    def gene_params(self, apiname, taskid=None, slice_id=None):\n",
    "        appid = self.appid\n",
    "        secret_key = self.secret_key\n",
    "        upload_file_path = self.upload_file_path\n",
    "        ts = str(int(time.time()))\n",
    "        m2 = hashlib.md5()\n",
    "        m2.update((appid + ts).encode('utf-8'))\n",
    "        md5 = m2.hexdigest()\n",
    "        md5 = bytes(md5, encoding='utf-8')\n",
    "        # 以secret_key为key, 上面的md5为msg， 使用hashlib.sha1加密结果为signa\n",
    "        signa = hmac.new(secret_key.encode('utf-8'), md5, hashlib.sha1).digest()\n",
    "        signa = base64.b64encode(signa)\n",
    "        signa = str(signa, 'utf-8')\n",
    "        file_len = os.path.getsize(upload_file_path)\n",
    "        file_name = os.path.basename(upload_file_path)\n",
    "        param_dict = {}\n",
    "\n",
    "        if apiname == api_prepare:\n",
    "            # slice_num是指分片数量，如果您使用的音频都是较短音频也可以不分片，直接将slice_num指定为1即可\n",
    "            slice_num = int(file_len / file_piece_sice) + (0 if (file_len % file_piece_sice == 0) else 1)\n",
    "            param_dict['app_id'] = appid\n",
    "            param_dict['signa'] = signa\n",
    "            param_dict['ts'] = ts\n",
    "            param_dict['file_len'] = str(file_len)\n",
    "            param_dict['file_name'] = file_name\n",
    "            param_dict['slice_num'] = str(slice_num)\n",
    "        elif apiname == api_upload:\n",
    "            param_dict['app_id'] = appid\n",
    "            param_dict['signa'] = signa\n",
    "            param_dict['ts'] = ts\n",
    "            param_dict['task_id'] = taskid\n",
    "            param_dict['slice_id'] = slice_id\n",
    "        elif apiname == api_merge:\n",
    "            param_dict['app_id'] = appid\n",
    "            param_dict['signa'] = signa\n",
    "            param_dict['ts'] = ts\n",
    "            param_dict['task_id'] = taskid\n",
    "            param_dict['file_name'] = file_name\n",
    "        elif apiname == api_get_progress or apiname == api_get_result:\n",
    "            param_dict['app_id'] = appid\n",
    "            param_dict['signa'] = signa\n",
    "            param_dict['ts'] = ts\n",
    "            param_dict['task_id'] = taskid\n",
    "        return param_dict\n",
    "\n",
    "    \n",
    "    # -----------------------------------------------新加的-----------------------------------------------\n",
    "    def getOnebest(self,result):\n",
    "        print(\"======================getOnebest======================\")\n",
    "        data_list = json.loads(result[\"data\"])\n",
    "        onebest_list = []\n",
    "        for data in data_list:\n",
    "            onebest = data[\"onebest\"]\n",
    "            onebest_list.append(onebest)\n",
    "        result_str = \"\".join(onebest_list)\n",
    "        print(result_str)\n",
    "    \n",
    "    # 请求和结果解析，结果中各个字段的含义可参考：https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html\n",
    "    def gene_request(self, apiname, data, files=None, headers=None):\n",
    "        response = requests.post(lfasr_host + apiname, data=data, files=files, headers=headers)\n",
    "        result = json.loads(response.text)\n",
    "        if result[\"ok\"] == 0:\n",
    "            print(\"{} 成功:\".format(apiname) + str(result))\n",
    "            if(apiname==\"/getResult\"):\n",
    "                self.getOnebest(response.json())\n",
    "            return result\n",
    "        else:\n",
    "            print(\"{} 成功:\".format(apiname) + str(result))\n",
    "            exit(0)\n",
    "            return result\n",
    "        \n",
    "\n",
    "\n",
    "    # 预处理\n",
    "    def prepare_request(self):\n",
    "        return self.gene_request(apiname=api_prepare,\n",
    "                                 data=self.gene_params(api_prepare))\n",
    "\n",
    "    # 上传\n",
    "    def upload_request(self, taskid, upload_file_path):\n",
    "        file_object = open(upload_file_path, 'rb')\n",
    "        try:\n",
    "            index = 1\n",
    "            sig = SliceIdGenerator()\n",
    "            while True:\n",
    "                content = file_object.read(file_piece_sice)\n",
    "                if not content or len(content) == 0:\n",
    "                    break\n",
    "                files = {\n",
    "                    \"filename\": self.gene_params(api_upload).get(\"slice_id\"),\n",
    "                    \"content\": content\n",
    "                }\n",
    "                response = self.gene_request(api_upload,\n",
    "                                             data=self.gene_params(api_upload, taskid=taskid,\n",
    "                                                                   slice_id=sig.getNextSliceId()),\n",
    "                                             files=files)\n",
    "                if response.get('ok') != 0:\n",
    "                    # 上传分片失败\n",
    "                    print('上传切片失败，响应： ' + str(response))\n",
    "                    return False\n",
    "                print('上传片' + str(index) + ' 成功')\n",
    "                index += 1\n",
    "        finally:\n",
    "            '文件索引：' + str(file_object.tell())\n",
    "            file_object.close()\n",
    "        return True\n",
    "\n",
    "    # 合并\n",
    "    def merge_request(self, taskid):\n",
    "        return self.gene_request(api_merge, data=self.gene_params(api_merge, taskid=taskid))\n",
    "\n",
    "    # 获取进度\n",
    "    def get_progress_request(self, taskid):\n",
    "        return self.gene_request(api_get_progress, data=self.gene_params(api_get_progress, taskid=taskid))\n",
    "\n",
    "    # 获取结果\n",
    "    def get_result_request(self, taskid):\n",
    "        return self.gene_request(api_get_result, data=self.gene_params(api_get_result, taskid=taskid))\n",
    "\n",
    "    def all_api_request(self):\n",
    "        # 1. 预处理\n",
    "        pre_result = self.prepare_request()\n",
    "        taskid = pre_result[\"data\"]\n",
    "        # 2 . 分片上传\n",
    "        self.upload_request(taskid=taskid, upload_file_path=self.upload_file_path)\n",
    "        # 3 . 文件合并\n",
    "        self.merge_request(taskid=taskid)\n",
    "        # 4 . 获取任务进度\n",
    "        while True:\n",
    "            # 每隔20秒获取一次任务进度\n",
    "            progress = self.get_progress_request(taskid)\n",
    "            progress_dic = progress\n",
    "            if progress_dic['err_no'] != 0 and progress_dic['err_no'] != 26605:\n",
    "                print('进程错误: ' + progress_dic['failed'])\n",
    "                return\n",
    "            else:\n",
    "                data = progress_dic['data']\n",
    "                task_status = json.loads(data)\n",
    "                if task_status['status'] == 9:\n",
    "                    print('进程 ' + taskid + ' 完成')\n",
    "                    break\n",
    "                print('这个进程 ' + taskid + ' 正在处理中，进程状态： ' + str(data))\n",
    "\n",
    "            # 每次获取进度间隔20S\n",
    "            time.sleep(20)\n",
    "        # 5 . 获取结果\n",
    "        self.get_result_request(taskid=taskid)\n",
    "\n",
    "#把结果存入文件\n",
    "# file = open(\"xunfei_translate_result.txt\", 'w')\n",
    "# file.write()\n",
    "# file.close()\n",
    "\n",
    "# 输入讯飞开放平台的appid，secret_key和待转写的文件路径\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    APP_ID = \"5fe5c2b1\"\n",
    "    SECRET_KEY = \"e6c1afeb926e1675abac3c792b1a03e9\"\n",
    "    file_path = r\"../test/test(news).m4a\"\n",
    "    api = RequestApi(appid=APP_ID, secret_key=SECRET_KEY, upload_file_path=file_path)\n",
    "    api.all_api_request()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getOnebest(self,result):\n",
    "    print(\"======================getOnebest======================\")\n",
    "    data_list = json.loads(result[\"data\"])\n",
    "    onebest_list = []\n",
    "    for data in data_list:\n",
    "        onebest = data[\"onebest\"]\n",
    "        onebest_list.append(onebest)\n",
    "    result_str = \"\".join(onebest_list)\n",
    "    print(result_str)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
